﻿using GTAFingerprinterCore.Core;
using GTAFingerprinterCore.Keyboards;
using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Imaging;

namespace GTAFingerprinterCore
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public Config Config { get; private set; }
        private HotKey FingerprinterHotKey { get; set; }
        private HotKey QuickClickHotKey { get; set; }

        private IFingerprinter Fingerprinter { get; set; }

        public MainWindow()
        {
            try
            {
                Log.Information("程序启动中……");
                //读取配置
                Config = Config.FromJsonFile("appsettings.json").GetAwaiter().GetResult();
                Fingerprinter = new Fingerprinter("Templates");
                InitializeComponent();

                //初始化指纹快捷键下拉框
                cbbFingerprinterKeys.ItemsSource = Enum.GetValues(typeof(System.Windows.Forms.Keys)).Cast<System.Windows.Forms.Keys>();
                cbbFingerprinterKeys.SelectedItem = Config.FingerprinterKey;
                cbbFingerprinterKeys.SelectionChanged += cbbFingerprinterKeys_Selection_Changed;
                //注册指纹快捷键
                RegisterFingerprinterHotKey(FingerprinterHotKey, Config.FingerprinterKey, FingerprinterKeyPress);

                //初始化连点快捷键下拉框
                cbbQuickClickKeys.ItemsSource = Enum.GetValues(typeof(System.Windows.Forms.Keys)).Cast<System.Windows.Forms.Keys>();
                cbbQuickClickKeys.SelectedItem = Config.QuickClickKey;
                cbbQuickClickKeys.SelectionChanged += cbbQuickClickKeys_Selection_Changed;
                //注册连点快捷键
                RegisterFingerprinterHotKey(FingerprinterHotKey, Config.QuickClickKey, QuickClickKeyPress);

                Log.Information("程序启动完成！");
            }
            catch (Exception e)
            {
                Log.Error($"程序启动失败\n{e.Message}\n{e.StackTrace}");
                MessageBox.Show(e.Message, "程序启动错误", MessageBoxButton.OK, MessageBoxImage.Error);
                Environment.Exit(1);
            }
        }

        private async void btnSaveCfg_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                await Config?.SaveConfig("appsettings.json");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "保存配置失败", MessageBoxButton.OK, MessageBoxImage.Error);
                Log.Error($"保存配置失败\n{ex.Message}\n{ex.StackTrace}");
            }
        }

        #region 热键相关

        private void cbbFingerprinterKeys_Selection_Changed(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                RegisterFingerprinterHotKey(FingerprinterHotKey, (System.Windows.Forms.Keys)cbbFingerprinterKeys.SelectedItem, FingerprinterKeyPress);
                Config.FingerprinterKey = (System.Windows.Forms.Keys)cbbFingerprinterKeys.SelectedItem;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "注册热键失败", MessageBoxButton.OK, MessageBoxImage.Error);
                Log.Error($"注册热键失败\n{ex.Message}\n{ex.StackTrace}");
            }
        }

        private void cbbQuickClickKeys_Selection_Changed(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                RegisterFingerprinterHotKey(QuickClickHotKey, (System.Windows.Forms.Keys)cbbQuickClickKeys.SelectedItem, QuickClickKeyPress);
                Config.QuickClickKey = (System.Windows.Forms.Keys)cbbQuickClickKeys.SelectedItem;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "注册热键失败", MessageBoxButton.OK, MessageBoxImage.Error);
                Log.Error($"注册热键失败\n{ex.Message}\n{ex.StackTrace}");
            }
        }

        /// <summary>
        /// 注册热键
        /// </summary>
        /// <param name="key"></param>
        private void RegisterFingerprinterHotKey(HotKey hotkey, System.Windows.Forms.Keys key, Action<HotKey> callBack)
        {
            try
            {
                if (hotkey != null)
                {
                    hotkey.Dispose();
                }
                hotkey = new HotKey(ModifierKeys.None, key, this);
                hotkey.HotKeyPressed += callBack;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 指纹快捷键被按下执行的操作
        /// </summary>
        /// <param name="key"></param>
        private async void FingerprinterKeyPress(HotKey key)
        {
            try
            {
                var img = await Fingerprinter.CaptureGameWindow(Config.FullScreenMode);
                Log.Information($"游戏截图截取成功");
                var big = await Fingerprinter.CutBig(img, Config.Big);
                var subs = await Fingerprinter.CutSubs(img, Config.Subs);
                ShowToWindow(big, subs);
                Log.Information($"以相似度{Config.Similarity}进行识别");
                var corrects = await Fingerprinter.Recognize(big, subs, Config.Similarity);
                Log.Information($"识别结束，结果为{string.Join(",", corrects)}");
                await Fingerprinter.AutoPressKeys(corrects, Config.KeyPressDelay);
            }
            catch (Exception e)
            {
                Log.Error($"{e.Message}\n{e.StackTrace}");
            }
        }

        /// <summary>
        /// 连击快捷键被按下执行的操作
        /// </summary>
        /// <param name="key"></param>
        private async void QuickClickKeyPress(HotKey key)
        {
            try
            {
                Keyboarder.MouseEvent(Keyboarder.MouseEventFlags.LeftDown);
                await Task.Delay(20);
                Keyboarder.MouseEvent(Keyboarder.MouseEventFlags.LeftUp);
                await Task.Delay(20);
            }
            catch (Exception e)
            {
                Log.Error($"{e.Message}\n{e.StackTrace}");
            }
        }

        #endregion 热键相关

        #region 显示图片到程序

        private void ShowToWindow(System.Drawing.Image big, IEnumerable<System.Drawing.Image> subs)
        {
            imgBig.Source = GetBitmapImage(big);
            var count = 0;
            foreach (var sub in subs)
            {
                Image a = FindName($"imgSub{count++}") as Image;
                a.Source = GetBitmapImage(sub);
            }
        }

        private BitmapImage GetBitmapImage(System.Drawing.Image image)
        {
            var ms = new MemoryStream();
            image.Save(ms, ImageFormat.Png);
            var bitimg = new BitmapImage();
            bitimg.BeginInit();
            bitimg.StreamSource = ms;
            bitimg.EndInit();
            bitimg.Freeze();
            return bitimg;
        }

        #endregion 显示图片到程序

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //await Generate();
            //await Test();
            var r = MessageBox.Show("支持UP，给个三连！", "支持一下吧！", MessageBoxButton.YesNo, MessageBoxImage.Information);
            if (r == MessageBoxResult.Yes)
            {
                OpenWebSite("https://www.bilibili.com/video/BV12p4y1U7B7/");
            }
            else
            {
                MessageBox.Show("白嫖使我快乐！", "白嫖鬼", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        #region 测试使用

        //private async Task Generate()
        //{
        //    var cofd = new CommonOpenFileDialog();
        //    cofd.IsFolderPicker = true;
        //    if (cofd.ShowDialog() == CommonFileDialogResult.Ok)
        //    {
        //        var dirInfo = new DirectoryInfo(cofd.FileName);
        //        var destInfo = new DirectoryInfo("Auto");
        //        if (!destInfo.Exists)
        //        {
        //            destInfo.Create();
        //        }
        //        int count = 1;
        //        foreach (var fileInfo in dirInfo.GetFiles().Where(x => x.Extension == ".png"))
        //        {
        //            var img = System.Drawing.Image.FromFile(fileInfo.FullName);
        //            img = ((Fingerpriter)Fingerprinter).Formatting(img);
        //            var big = await Fingerprinter.CutBig(img, Config.Big);
        //            big.Save(Path.Combine(destInfo.FullName, $"{count}.png"), ImageFormat.Png);//保存大图
        //            big.Dispose();
        //            var subs = await Fingerprinter.CutSubs(img, Config.Subs);
        //            var subDir = Path.Combine(destInfo.FullName, count.ToString());
        //            if (!Directory.Exists(subDir))
        //            {
        //                Directory.CreateDirectory(subDir);
        //            }
        //            int subc = 0;
        //            foreach (var sub in subs)
        //            {
        //                sub.Save(Path.Combine(subDir, $"{subc++}.png"));
        //                sub.Dispose();
        //            }
        //            count++;
        //        }
        //    }
        //}

        //private async Task Test()
        //{
        //    var cofd = new CommonOpenFileDialog();
        //    if (cofd.ShowDialog() == CommonFileDialogResult.Ok)
        //    {
        //        var img = System.Drawing.Image.FromFile(cofd.FileName);
        //        img = ((Fingerpriter)Fingerprinter).Formatting(img);
        //        var big = await Fingerprinter.CutBig(img, Config.Big);
        //        var subs = await Fingerprinter.CutSubs(img, Config.Subs);
        //        ShowToWindow(big, subs);
        //        var corrects = await Fingerprinter.Recognize(big, subs, Config.Similarity);
        //        big.Dispose();
        //        foreach (var sub in subs)
        //        {
        //            sub.Dispose();
        //        }
        //        MessageBox.Show(string.Join(",", corrects));
        //    }
        //}

        #endregion 测试使用

        private void Hyperlink_Click(object sender, RoutedEventArgs e)
        {
            OpenWebSite((sender as Hyperlink).NavigateUri.AbsoluteUri);
        }

        private void OpenWebSite(string link)
        {
            var targetURL = link;
            var psi = new ProcessStartInfo
            {
                FileName = targetURL,
                UseShellExecute = true
            };
            Process.Start(psi);
        }
    }
}